﻿//
// Copyright (c) 2024 BPer
//
#include <bperrtc/BPerPlayTrackAudio.h>
#include <bperrtc/BPerPlayTrack.h>

#include <bperutil/sys/BPerLog.h>

#include <bperrtp/BPerRtpHeader.h>
#include <bperrtp/BPerRtpRawPayload.h>
#include <bperrtp/BPerRtpFUAPayload2.h>
#include <bperrtp/BPerRtpSTAPPayload.h>



#if BPer_Enable_RTC_Audio

int32_t bPer_playtrackAudio_on_rtp(BPerRtcContext *context, BPerPlayTrack* track,BPerRtpPacket *ppkt) {
	int32_t err = BPer_Ok;

	if (ppkt->payload) {
		track->audioFrame.uid = context->streamConfig->uid;
		track->audioFrame.payload = (uint8_t*) ppkt->payload;
		track->audioFrame.nb = ppkt->nb;
		track->audioFrame.pts = ppkt->header.timestamp;

		if(track&&track->sortBuffer){
			track->sortBuffer->putFrame(&track->sortBuffer->session,track->audioFrame.pts,&track->audioFrame);
			BPerFrame* frame=track->sortBuffer->getCurFrameRef(&track->sortBuffer->session);
			if (frame&&context){
				if(context->streamConfig->recvCallback.receiveAudio)
					context->streamConfig->recvCallback.receiveAudio(context->streamConfig->recvCallback.context,frame);
				track->sortBuffer->removeFirst(&track->sortBuffer->session);
			}

		}else{
			if (context && context->streamConfig->recvCallback.receiveAudio)
				context->streamConfig->recvCallback.receiveAudio(context->streamConfig->recvCallback.context,&track->audioFrame);
		}
	}

	return err;
}

int32_t bPer_playtrackAudio_check_send_nacks(BPerRtcContext *context,
		BPerPlayTrack *audiorecv) {
	int32_t err = BPer_Ok;
	uint32_t timeout_nacks = 0;
	if ((err = bPer_playtrack_do_check_send_nacks(context, audiorecv,
			&timeout_nacks)) != BPer_Ok) {
		return bPer_error_wrap(err, "audio");
	}

	return err;
}

int32_t bPer_playtrackAudio_send_rtcp_rr(BPerRtcContext *context,BPerPlayTrack *track){
	return bPer_playtrack_send_rtcp_rr(context,BPerTrue,track);
}

void bPer_create_playTrackAudio(BPerRtcContext *context, BPerPlayTrackAudio *track) {
	bPer_create_playTrack(context, &track->session,BPerTrue);

	if(track->session.enableAudioBuffer&&track->session.sortBuffer==NULL){
		track->session.sortBuffer=(BPerSortBuffer*)bPer_calloc(sizeof(BPerSortBuffer),1);
		bPer_create_sortBuffer(track->session.sortBuffer,3);
		track->session.sortBuffer->initFrames(&track->session.sortBuffer->session,8,1500);
	}

	track->on_rtp=bPer_playtrackAudio_on_rtp;
	track->check_nacks=bPer_playtrackAudio_check_send_nacks;
	track->has_ssrc=bPer_playtrack_has_ssrc;
	track->update_rtt=bPer_playtrack_update_rtt;
	track->update_send_report_time=bPer_playtrack_update_send_report_time;
	track->send_rtcp_rr=bPer_playtrackAudio_send_rtcp_rr;
	track->send_rtcp_xr_rrtr=bPer_playtrack_send_rtcp_xr_rrtr;
	track->on_nack=bPer_playtrack_on_nack;
}
void bPer_destroy_playTrackAudio(BPerPlayTrackAudio *track) {
	bPer_destroy_sortBuffer(track->session.sortBuffer);
	bPer_free(track->session.sortBuffer);
	bPer_destroy_playTrack(&track->session);
}
#endif
